package com.janko.springbootbase.juc.threadLocal;

import java.util.concurrent.TimeUnit;


/**
 * FIXME ThreadLocal的特性，同一线程在某地方进行设置，在随后的任意地方都可以获取到。从而可以用来保存线程上下文信息。
 * 还是线程安全的
 */
public class AQS_ThreadLocal1 {

    volatile static Person p =new Person();
    static ThreadLocal<Person> tp =new ThreadLocal<Person>();
    public static void main(String[] args) {
        normal();
        threadLocalTest();
    }
    private static void threadLocalTest() {
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            /**
             * 打印出来的值为空  原因是：ThreadLocal里边源码是
             */
            System.out.println(Thread.currentThread().getName()+": ===> "+tp.get());
        },"tp2").start();

        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            tp.set(new Person());
        },"tp1").start();
    }

    private static void normal() {
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            // 可以打印出来 线程t1的结果值
            System.out.println(Thread.currentThread().getName()+": ===> "+ p.name);

            //当执行以下操作的时候，调用 System.GC()，那么被finalize重写的这个对象会被回收了
            p=null;
            System.gc();

        },"t2").start();

        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            p.name="李四";
        },"t1").start();
    }
}
class Person {
    String name="张三";

    //  当该类被回收的时候，就会执行以下的方法 ！！！！！除非测试，不要去重写这个方法  finalize
    @Override
    protected void finalize() throws Throwable {
        System.out.println("重写了 finalize");
    }
}
